package com.xinsoft.controller.qua;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xinsoft.aop.ano.SysLog;
import com.xinsoft.common.BusinessType;
import com.xinsoft.common.Response;
import com.xinsoft.constant.Const;
import com.xinsoft.entity.dto.QuaCheckPlanParam;
import com.xinsoft.entity.po.*;
import com.xinsoft.service.*;
import com.xinsoft.utils.TokenUtil;
import com.xinsoft.validator.ValidatorUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @ClassName QuaCheckPlanController
 * @Description 检验方案控制层
 * @Author Li9527
 * @Date 2023-7-17 15:43:16
 * @Version 1.0
 */
@RestController
@RequestMapping("/qua/checkPlan")
@Api(value = "QuaCheckPlanController", tags = {"检验方案控制层"})
public class QuaCheckPlanController {

    @Autowired
    private QuaCheckPlanService quaCheckPlanService;

    @Autowired
    private QuaDocumentService documentService;

    @Autowired
    private QuaPlanCheckRefService planCheckRefService;

    @Autowired
    private QuaCheckItemService checkItemService;

    @Autowired
    private SysFileHisService fileHisService;

    @Autowired
    private SysUserService userService;
    @Autowired
    private SysMaterialService materialService;
    @Autowired
    private SysDictionaryService dictionaryService;

    @Autowired
    private SysDocumentNumService sysDocumentNumService;

    /**
     * @Author Li9527
     * @Description 检验方案-新增
     * @Date 2023/5/17 9:57
     * @params   dept
     * @return com.xinsoft.common.Response<?>
     **/
    @SysLog(title = "检验方案-新增", businessType = BusinessType.INSERT)
    @ApiOperation("新增")
    @PostMapping("/add")
    public Response<?> add(@RequestBody QuaCheckPlan checkPlan) {
        // 参数校验
        ValidatorUtils.validateEntity(checkPlan);
        // 默认已审核
        checkPlan.setAuditId(Const.ADMIN_UID);
        checkPlan.setAuditStatus(Const.AUDIT_STATUS_NORMAL);
        QuaCheckPlan oldCheckPlan = quaCheckPlanService.getOne(new QueryWrapper<QuaCheckPlan>().eq("check_plan_name",checkPlan.getCheckPlanName()));
        if(oldCheckPlan != null){
            return Response.fail("该检验方案已存在,请不要重复添加");
        }
        sysDocumentNumService.incrementLastSerialByDocumentId(Const.DOCUMENT_ID.CHECK_WAYS_DOCUMENT);
        quaCheckPlanService.save(checkPlan);
        if (checkPlan.getSysFileHisList().size() > 0) {
            // 质量文档
            this.saveDocumentlList(checkPlan);
        }
        if (checkPlan.getCheckItemList().size() > 0) {
            // 检验项
            this.saveItemList(checkPlan);
        }
        return Response.succeed();
    }

    /**
     * @Author Li9527
     * @Description 更新
     * @Date 2023/5/17 9:57
     * @params   dept
     * @return com.xinsoft.common.Response<?>
     **/
    @ApiOperation("更新")
    @SysLog(title = "检验方案-编辑", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    public Response<?> edit(@RequestBody QuaCheckPlan checkPlan) {
        // 参数校验
        QuaCheckPlan oldCheckPlan = quaCheckPlanService.getOne(new QueryWrapper<QuaCheckPlan>().eq("check_plan_name",checkPlan.getCheckPlanName()));
        if(oldCheckPlan != null && !checkPlan.getId().equals(oldCheckPlan.getId())){
            return Response.fail("该检验方案已存在,请不要重复添加");
        }
        ValidatorUtils.validateEntity(checkPlan);
        if (checkPlan.getSysFileHisList().size() > 0) {
            // 质量文档
            documentService.remove(new QueryWrapper<QuaDocument>().eq("qua_id", checkPlan.getId()).eq("qua_type",Const.DOCUMENT_QUA_TYPE.CHECK_ITEM));
            this.saveDocumentlList(checkPlan);
        }
        if (checkPlan.getCheckItemList().size() > 0) {
            // 检验项
            planCheckRefService.remove(new QueryWrapper<QuaPlanCheckRef>().eq("plan_id", checkPlan.getId()));
            this.saveItemList(checkPlan);
        }
        return Response.succeed(quaCheckPlanService.updateById(checkPlan));
    }

    /**
     * 获取详情
     * @folder 质量管理/检验方案
     * @Author Li9527
     * @Description 获取详情
     * @Date 2023/5/17 9:57
     * @params   id
     * @return com.xinsoft.common.Response<?>
     **/
    @ApiOperation("获取详情")
    @GetMapping("/detail")
    public Response<QuaCheckPlan> detail(@RequestParam(value = "id", defaultValue = "", required = true) Integer id) {
        QuaCheckPlan checkPlan = quaCheckPlanService.getById(id);
        // 组装检验物料名称
        JSONArray jsonArray = JSONUtil.parseArray(checkPlan.getCheckMaterialIds());
        List<Integer> materialIds = jsonArray.toList(Integer.class);
        if (CollectionUtil.isNotEmpty(materialIds)){
            List<SysMaterial> materialList = materialService.listByIds(materialIds);
            checkPlan.setCheckMaterialNameList(materialList.stream().map(SysMaterial::getMaterialName).collect(Collectors.toList()));
        }
        // 组装检验类型名称
        SysDictionary dictionary = dictionaryService.getById(checkPlan.getCheckTypeId());
        checkPlan.setCheckTypeName(Objects.isNull(dictionary)?null:dictionary.getDicName());
        // 组装文件列表
        List<QuaDocument> mesDocumentList  = documentService.list(new QueryWrapper<QuaDocument>().eq("qua_id", id).eq("qua_type",Const.DOCUMENT_QUA_TYPE.CHECK_PLAN));
        List<Integer> fileIds = new ArrayList<>();
        for (int i = 0; i < mesDocumentList.size(); i++) {
            fileIds.add(mesDocumentList.get(i).getDocumentId());
        }
        if (mesDocumentList.size() > 0) {
            List<SysFileHis> sysFileHis = fileHisService.listByIds(fileIds);
            checkPlan.setSysFileHisList(sysFileHis);
        }
        // 组装检验方案列表
        List<QuaPlanCheckRef> planCheckRefList  = planCheckRefService.list(new QueryWrapper<QuaPlanCheckRef>().eq("plan_id", id));
        List<Integer> fileRefIds = new ArrayList<>();
        for (int i = 0; i < planCheckRefList.size(); i++) {
            fileRefIds.add(planCheckRefList.get(i).getCheckId());
        }
        if (planCheckRefList.size() > 0) {
            List<QuaCheckItem> checkItemList = checkItemService.listByIds(fileRefIds);
            for (int i = 0; i < checkItemList.size(); i++) {
                QuaPlanCheckRef ref = planCheckRefService.getOne(new QueryWrapper<QuaPlanCheckRef>()
                .eq("plan_id",id).eq("check_id",checkItemList.get(i).getId()));
                checkItemList.get(i).setGoatUnit(ref.getGoatUnit());
                checkItemList.get(i).setGoatValue(ref.getGoatValue());
            }
            checkPlan.setCheckItemList(checkItemList);
        }
        // 组装制单人名称和审核人名称
        if(checkPlan.getCreateBy() != null){
            checkPlan.setCreateUser(userService.getById(checkPlan.getCreateBy()).getRealName());
        }
        if(checkPlan.getAuditId() != null){
            checkPlan.setAuditUser(userService.getById(checkPlan.getAuditId()).getRealName());
        }
        return Response.succeed(checkPlan);
    }

    /**
     * @Author Li9527
     * @Description 删除
     * @Date 2023/5/12 9:20
     * @params   ids
     * @return com.xinsoft.common.Response<?>
     **/
    @ApiOperation("删除")
    @SysLog(title = "检验方案-删除", businessType = BusinessType.DELETE)
    @PostMapping("/del")
    public Response<?> del(@RequestBody List<Integer> ids) {
        for (int i = 0; i < ids.size(); i++) {
            QuaCheckPlan quaCheckPlan = quaCheckPlanService.getById(ids.get(i));
            if(quaCheckPlan != null && quaCheckPlan.getAuditStatus().equals(Const.AUDIT_STATUS_NORMAL)){
                return Response.fail("存在已审核检验方案，不允许删除");
            }
        }
        quaCheckPlanService.removeByIds(ids);
        return Response.succeed();
    }

    /**
     * @Author Li9527
     * @Description 检验方案分页
     * @Date 2023/5/18 10:51
     * @params   param
     * @return com.xinsoft.common.Response<?>
     **/
    @PostMapping("/pageList")
    public Response<?> pageList(@Valid @RequestBody QuaCheckPlanParam param) {
        return Response.succeed(quaCheckPlanService.findPageListByParam(param));
    }

    /**
     * @Author Li9527
     * @Description 批量审核
     * @Date 2023/5/12 9:20
     * @params   ids
     * @return com.xinsoft.common.Response<?>
     **/
    @ApiOperation("检验方案-批量审核")
    @SysLog(title = "检验方案-批量审核", businessType = BusinessType.UPDATE)
    @PostMapping("/auditBatch")
    public Response<?> auditBacth(@RequestBody List<Integer> ids) {
        Integer auditId =  TokenUtil.getUser().getId();
        List<QuaCheckPlan> list = quaCheckPlanService.list(new QueryWrapper<QuaCheckPlan>().in("id",ids));
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setAuditStatus(Const.AUDIT_STATUS_NORMAL);
            list.get(i).setAuditId(auditId);
        }
        quaCheckPlanService.updateBatchById(list);
        return Response.succeed();
    }

    /**
     * @Author Li9527
     * @Description 批量反审核
     * @Date 2023/5/12 9:20
     * @params   ids
     * @return com.xinsoft.common.Response<?>
     **/
    @ApiOperation("检验方案-批量反审核")
    @SysLog(title = "检验方案-批量反审核", businessType = BusinessType.UPDATE)
    @PostMapping("/unAuditBatch")
    public Response<?> unAuditBatch(@RequestBody List<Integer> ids) {
        List<QuaCheckPlan> list = quaCheckPlanService.list(new QueryWrapper<QuaCheckPlan>().in("id",ids));
        Integer auditId =  TokenUtil.getUser().getId();
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setAuditStatus(Const.AUDIT_STATUS_WAIT);
            list.get(i).setAuditId(auditId);
        }
        quaCheckPlanService.updateBatchById(list);
        return Response.succeed();
    }

    private void saveItemList(QuaCheckPlan checkPlan) {
        for (int i = 0; i < checkPlan.getCheckItemList().size(); i++) {
            QuaPlanCheckRef ref = new QuaPlanCheckRef();
            BeanUtil.copyProperties(checkPlan.getCheckItemList().get(i),ref);
            ref.setPlanId(checkPlan.getId());
            ref.setCheckId(checkPlan.getCheckItemList().get(i).getId());
            planCheckRefService.save(ref);
        }
    }

    private void saveDocumentlList(QuaCheckPlan quaCheckPlan) {
        if (quaCheckPlan.getSysFileHisList() != null && quaCheckPlan.getSysFileHisList().size() > 0) {
            List<QuaDocument> quaDocumentList = new ArrayList<>();
            for (int i = 0; i < quaCheckPlan.getSysFileHisList().size(); i++) {
                QuaDocument quaDocument = new QuaDocument();
                quaDocument.setQuaId(quaCheckPlan.getId());
                quaDocument.setQuaType(Const.DOCUMENT_QUA_TYPE.CHECK_PLAN);
                quaDocument.setDocumentId(quaCheckPlan.getSysFileHisList().get(i).getId());
                quaDocumentList.add(quaDocument);
            }
            documentService.saveBatch(quaDocumentList);
        }
    }

}
